import { Injectable, NotFoundException, ConflictException, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, SelectQueryBuilder } from 'typeorm';
import { User } from './entities/user.entity';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { QueryUsersDto } from './dto/query-users.dto';
import { PaginationResponseDto } from '../common/dto/pagination.dto';
import * as bcrypt from 'bcryptjs';

@Injectable()
export class UsersService {
  private readonly logger = new Logger(UsersService.name);

  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  async create(createUserDto: CreateUserDto): Promise<User> {
    this.logger.log(`创建用户请求: ${JSON.stringify(createUserDto)}`);
    
    // 检查用户名是否已存在
    const existingUser = await this.usersRepository.findOne({
      where: [
        { username: createUserDto.username },
        { email: createUserDto.email }
      ]
    });

    if (existingUser) {
      this.logger.warn(`用户创建失败: 用户名或邮箱已存在 - ${createUserDto.username}`);
      throw new ConflictException('用户名或邮箱已存在');
    }

    // 加密密码
    const hashedPassword = await bcrypt.hash(createUserDto.password, 10);
    this.logger.log(`密码加密完成，原始长度: ${createUserDto.password.length}, 加密后长度: ${hashedPassword.length}`);

    const user = this.usersRepository.create({
      ...createUserDto,
      password: hashedPassword,
    });

    const savedUser = await this.usersRepository.save(user);
    this.logger.log(`用户创建成功: ${savedUser.username}, ID: ${savedUser.id}`);
    
    return savedUser;
  }

  async findAll(): Promise<User[]> {
    this.logger.log('获取所有用户列表');
    const users = await this.usersRepository.find({
      select: ['id', 'username', 'email', 'nickname', 'role', 'isActive', 'lastLoginAt', 'createdAt', 'updatedAt']
    });
    this.logger.log(`找到 ${users.length} 个用户`);
    return users;
  }

  async findWithPagination(queryDto: QueryUsersDto): Promise<PaginationResponseDto<User>> {
    this.logger.log(`分页查询用户: ${JSON.stringify(queryDto)}`);

    const {
      page = 1,
      pageSize = 10,
      keyword,
      username,
      email,
      nickname,
      role,
      isActive,
      startDate,
      endDate,
      sortBy = 'createdAt',
      sortOrder = 'DESC'
    } = queryDto;

    // 构建查询
    const queryBuilder = this.buildUserQueryBuilder({
      keyword,
      username,
      email,
      nickname,
      role,
      isActive,
      startDate,
      endDate
    });

    // 添加排序
    queryBuilder.orderBy(`User.${sortBy}`, sortOrder);

    // 获取总数
    const total = await queryBuilder.getCount();
    this.logger.log(`查询到总用户数: ${total}`);

    // 分页查询
    const skip = (page - 1) * pageSize;
    const users = await queryBuilder
      .select([
        'User.id',
        'User.username',
        'User.email',
        'User.nickname',
        'User.role',
        'User.isActive',
        'User.lastLoginAt',
        'User.createdAt',
        'User.updatedAt'
      ])
      .skip(skip)
      .take(pageSize)
      .getMany();

    this.logger.log(`分页查询结果: 第${page}页，每页${pageSize}条，实际返回${users.length}条`);

    // 计算分页信息
    const totalPages = Math.ceil(total / pageSize);
    const hasPrevious = page > 1;
    const hasNext = page < totalPages;

    return {
      data: users,
      total,
      page,
      pageSize,
      totalPages,
      hasPrevious,
      hasNext
    };
  }

  private buildUserQueryBuilder(filters: {
    keyword?: string;
    username?: string;
    email?: string;
    nickname?: string;
    role?: string;
    isActive?: boolean;
    startDate?: string;
    endDate?: string;
  }): SelectQueryBuilder<User> {
    const queryBuilder = this.usersRepository.createQueryBuilder('User');

    // 关键词搜索（用户名、邮箱、昵称）
    if (filters.keyword) {
      queryBuilder.andWhere(
        '(User.username LIKE :keyword OR User.email LIKE :keyword OR User.nickname LIKE :keyword)',
        { keyword: `%${filters.keyword}%` }
      );
    }

    // 用户名搜索
    if (filters.username) {
      queryBuilder.andWhere('User.username LIKE :username', { username: `%${filters.username}%` });
    }

    // 邮箱搜索
    if (filters.email) {
      queryBuilder.andWhere('User.email LIKE :email', { email: `%${filters.email}%` });
    }

    // 昵称搜索
    if (filters.nickname) {
      queryBuilder.andWhere('User.nickname LIKE :nickname', { nickname: `%${filters.nickname}%` });
    }

    // 角色筛选
    if (filters.role) {
      queryBuilder.andWhere('User.role = :role', { role: filters.role });
    }

    // 激活状态筛选
    if (filters.isActive !== undefined) {
      queryBuilder.andWhere('User.isActive = :isActive', { isActive: filters.isActive });
    }

    // 时间范围筛选
    if (filters.startDate) {
      queryBuilder.andWhere('User.createdAt >= :startDate', { startDate: filters.startDate });
    }
    if (filters.endDate) {
      queryBuilder.andWhere('User.createdAt <= :endDate', { endDate: filters.endDate });
    }

    return queryBuilder;
  }

  async findOne(id: number): Promise<User> {
    this.logger.log(`查找用户ID: ${id}`);
    
    const user = await this.usersRepository.findOne({
      where: { id },
      select: ['id', 'username', 'email', 'nickname', 'role', 'isActive', 'lastLoginAt', 'createdAt', 'updatedAt']
    });

    if (!user) {
      this.logger.warn(`用户不存在: ID ${id}`);
      throw new NotFoundException(`用户ID ${id} 不存在`);
    }

    this.logger.log(`找到用户: ${user.username}, ID: ${user.id}`);
    return user;
  }

  async findByUsername(username: string): Promise<User | null> {
    this.logger.log(`根据用户名查找用户: ${username}`);
    
    const user = await this.usersRepository.findOne({ 
      where: { username },
      select: ['id', 'username', 'email', 'password', 'nickname', 'role', 'isActive', 'lastLoginAt', 'createdAt', 'updatedAt']
    });
    
    if (user) {
      this.logger.log(`找到用户: ${username}, ID: ${user.id}, 角色: ${user.role}, 密码长度: ${user.password.length}`);
    } else {
      this.logger.warn(`用户不存在: ${username}`);
    }
    
    return user;
  }

  async update(id: number, updateUserDto: UpdateUserDto): Promise<User> {
    this.logger.log(`更新用户ID: ${id}, 更新数据: ${JSON.stringify(updateUserDto)}`);
    
    const user = await this.findOne(id);

    // 如果要更新密码，需要加密
    if (updateUserDto.password) {
      const hashedPassword = await bcrypt.hash(updateUserDto.password, 10);
      updateUserDto.password = hashedPassword;
      this.logger.log(`密码已重新加密，新密码长度: ${hashedPassword.length}`);
    }

    // 检查用户名和邮箱唯一性
    if (updateUserDto.username || updateUserDto.email) {
      const existingUser = await this.usersRepository.findOne({
        where: [
          { username: updateUserDto.username || user.username },
          { email: updateUserDto.email || user.email }
        ]
      });

      if (existingUser && existingUser.id !== id) {
        this.logger.warn(`用户更新失败: 用户名或邮箱已存在 - ${updateUserDto.username || user.username}`);
        throw new ConflictException('用户名或邮箱已存在');
      }
    }

    Object.assign(user, updateUserDto);
    const updatedUser = await this.usersRepository.save(user);
    this.logger.log(`用户更新成功: ${updatedUser.username}, ID: ${updatedUser.id}`);
    
    return updatedUser;
  }

  async remove(id: number): Promise<void> {
    this.logger.log(`删除用户ID: ${id}`);
    
    const user = await this.findOne(id);
    await this.usersRepository.remove(user);
    
    this.logger.log(`用户删除成功: ${user.username}, ID: ${id}`);
  }

  async updateLastLogin(id: number): Promise<void> {
    this.logger.log(`更新用户最后登录时间: ID ${id}`);
    
    await this.usersRepository.update(id, { lastLoginAt: new Date() });
    this.logger.log(`用户最后登录时间更新成功: ID ${id}`);
  }
}
